package org.realogic.cfm.util;

import java.util.Calendar;
import java.util.GregorianCalendar;

public final class UtilDateTime {

	public static java.util.Date getDate(java.util.Date theDate, int days) {
		GregorianCalendar c = new GregorianCalendar();
		// Calendar c = Calendar.getInstance();
		c.setTime(theDate);
		c.add(Calendar.DATE, days);
		return c.getTime();
	}

	public static java.util.Date getDateOfMinute(java.util.Date theDate, int minute) {
		GregorianCalendar c = new GregorianCalendar();
		// Calendar c = Calendar.getInstance();
		c.setTime(theDate);
		c.add(Calendar.MINUTE, minute);
		return c.getTime();
	}

	public static int getDaysBetween(java.util.Date start, java.util.Date end) {
		boolean negative = false;
		if (end.before(start)) {
			negative = true;
			java.util.Date temp = start;
			start = end;
			end = temp;
		}
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(start);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		GregorianCalendar calEnd = new GregorianCalendar();
		calEnd.setTime(end);
		calEnd.set(Calendar.HOUR_OF_DAY, 0);
		calEnd.set(Calendar.MINUTE, 0);
		calEnd.set(Calendar.SECOND, 0);
		calEnd.set(Calendar.MILLISECOND, 0);
		if (cal.get(Calendar.YEAR) == calEnd.get(Calendar.YEAR)) {
			if (negative) {
				return (calEnd.get(Calendar.DAY_OF_YEAR) - cal.get(Calendar.DAY_OF_YEAR)) * -1;
			}
			return calEnd.get(Calendar.DAY_OF_YEAR) - cal.get(Calendar.DAY_OF_YEAR);
		}
		int counter = 0;
		while (calEnd.after(cal)) {
			cal.add(Calendar.DAY_OF_YEAR, 1);
			counter++;
		}
		if (negative) {
			return counter * -1;
		}
		return counter;
	}

	public static int getMonthsBetween(java.util.Date start) {
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(start);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		GregorianCalendar calEnd = new GregorianCalendar();
		return getMonthsBetween(cal, calEnd);
	}

	public static int getMonthsBetween(java.util.Date start, java.util.Date end) {
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(start);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		GregorianCalendar calEnd = new GregorianCalendar();
		calEnd.setTime(end);
		calEnd.set(Calendar.HOUR_OF_DAY, 0);
		calEnd.set(Calendar.MINUTE, 0);
		calEnd.set(Calendar.SECOND, 0);
		calEnd.set(Calendar.MILLISECOND, 0);
		return getMonthsBetween(cal, calEnd);
	}

	public static int getMonthsBetween(GregorianCalendar pFormer, GregorianCalendar pLatter) {
		GregorianCalendar vFormer = pFormer, vLatter = pLatter;
		boolean vPositive = true;
		if (pFormer.before(pLatter)) {
			vFormer = pFormer;
			vLatter = pLatter;
		} else {
			vFormer = pLatter;
			vLatter = pFormer;
			vPositive = false;
		}

		int vCounter = 0;
		while (vFormer.get(Calendar.YEAR) != vLatter.get(Calendar.YEAR) || vFormer.get(Calendar.MONTH) != vLatter.get(Calendar.MONTH)) {
			vFormer.add(Calendar.MONTH, 1);
			vCounter++;
		}
		if (vPositive)
			return vCounter;
		else
			return -vCounter;
	}

	public static java.sql.Timestamp getDayStart(java.sql.Timestamp stamp, int daysLater) {
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new java.util.Date(stamp.getTime()));
		tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		tempCal.add(Calendar.DAY_OF_MONTH, daysLater);
		java.sql.Timestamp retStamp = new java.sql.Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	public static java.sql.Timestamp getDayEnd(java.sql.Timestamp stamp, int daysLater) {
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new java.util.Date(stamp.getTime()));
		tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
		tempCal.add(Calendar.DAY_OF_MONTH, daysLater);
		java.sql.Timestamp retStamp = new java.sql.Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(999999999);
		return retStamp;
	}

	public static java.util.Date getCurrentDate() {
		return new java.util.Date(System.currentTimeMillis());
	}

	public static java.sql.Date getCurrentSqlDate() {
		return new java.sql.Date(System.currentTimeMillis());
	}

	public static java.sql.Timestamp getCurrentTimestamp() {
		return new java.sql.Timestamp(System.currentTimeMillis());
	}

	public static java.sql.Time getCurrenSqlTime() {
		return new java.sql.Time(System.currentTimeMillis());
	}

	public static java.sql.Timestamp getTimestamp(String yyyymmdd, String hh, String ss) {
		String s = yyyymmdd.trim() + " " + hh.trim() + ":" + ss.trim() + ":0";
		return java.sql.Timestamp.valueOf(s);
	}

	public static java.sql.Timestamp getYearStart(int year) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, 0, 1, 0, 0, 0);
		java.sql.Timestamp retStamp = new java.sql.Timestamp(calendar.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	public static java.sql.Timestamp getYearEnd(int year) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, 11, 31, 23, 59, 59);
		java.sql.Timestamp retStamp = new java.sql.Timestamp(calendar.getTime().getTime());
		retStamp.setNanos(999999999);
		return retStamp;
	}

	// 获取某时间所在月的开始时间
	public static java.sql.Timestamp getMonthStart(java.sql.Timestamp stamp) {
		return getMonthStart(stamp, 0);
	}

	public static java.sql.Timestamp getMonthStart(java.sql.Timestamp stamp, int daysLater) {
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new java.util.Date(stamp.getTime()));
		tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), 1, 0, 0, 0);
		tempCal.add(Calendar.DAY_OF_MONTH, daysLater);
		java.sql.Timestamp retStamp = new java.sql.Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	// 获取某年份和月份的开始时间
	public static java.sql.Timestamp getMonthStart(int year, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, 1, 0, 0, 0);
		java.sql.Timestamp retStamp = new java.sql.Timestamp(calendar.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	// 获取某年份和月份的结束时间
	public static java.sql.Timestamp getMonthEnd(int year, int month) {
		java.sql.Timestamp nextStamp = getMonthStart(year, month + 1);
		java.sql.Timestamp endMonthDay = getDayEnd(nextStamp, -1);
		return endMonthDay;
	}

	// 获取某年份和月份的最后一天
	public static int getDayEnd(int year, int month) {
		java.sql.Timestamp nextStamp = getMonthStart(year, month + 1);
		java.sql.Timestamp endMonthDay = getDayEnd(nextStamp, -1);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(endMonthDay);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	// 获取某时间所在周的开始时间
	public static java.sql.Timestamp getWeekStart(java.sql.Timestamp stamp) {
		return getWeekStart(stamp, 0);
	}

	// 获取某时间所在周的结束时间
	public static java.sql.Timestamp getWeekEnd(java.sql.Timestamp stamp) {
		return getDayEnd(getWeekStart(new java.sql.Timestamp(System.currentTimeMillis())), 6);
	}

	public static java.sql.Timestamp getWeekStart(java.sql.Timestamp stamp, int daysLater) {
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new java.util.Date(stamp.getTime()));
		tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		tempCal.add(Calendar.DAY_OF_MONTH, daysLater);
		tempCal.set(Calendar.DAY_OF_WEEK, tempCal.getFirstDayOfWeek());
		java.sql.Timestamp retStamp = new java.sql.Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

	public static java.sql.Timestamp getCurrentTimeStart() {
		java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
		String s = date.toString() + " 0:0:0";
		return java.sql.Timestamp.valueOf(s);
	}

	public static java.sql.Timestamp getCurrentTimeEnd() {
		java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
		String s = date.toString() + " 23:59:59";
		return java.sql.Timestamp.valueOf(s);
	}

	public static String dateToStr36(java.util.Date theDate) {
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(theDate);
		int sYear = tempCal.get(Calendar.YEAR) - 2000;
		int sMonth = tempCal.get(Calendar.MONTH) + 1;
		int sDay = tempCal.get(Calendar.DAY_OF_MONTH);
		String tmp = Integer.toString(sYear, 36) + Integer.toString(sMonth, 36) + Integer.toString(sDay, 36);
		return tmp.toUpperCase();
	}

	public static java.util.Date str36ToDate(String theDateStr) {
		int year = 2000 + Integer.valueOf(String.valueOf(theDateStr.charAt(0)), 36);
		int month = Integer.valueOf(String.valueOf(theDateStr.charAt(1)), 36) - 1;
		int day = Integer.valueOf(String.valueOf(theDateStr.charAt(2)), 36);
		Calendar tempCal = Calendar.getInstance();
		tempCal.set(year, month, day, 0, 0, 0);
		return tempCal.getTime();
	}

	public static java.sql.Date str36ToSqlDate(String theDateStr) {
		int year = 2000 + Integer.valueOf(String.valueOf(theDateStr.charAt(0)), 36);
		int month = Integer.valueOf(String.valueOf(theDateStr.charAt(1)), 36) - 1;
		int day = Integer.valueOf(String.valueOf(theDateStr.charAt(2)), 36);
		Calendar tempCal = Calendar.getInstance();
		tempCal.set(year, month, day, 0, 0, 0);
		return new java.sql.Date(tempCal.getTime().getTime());
	}
	
	public static java.sql.Timestamp getCurrentTimeEnd(int timeLater) {
		Calendar tempCal = Calendar.getInstance();
		tempCal.setTime(new java.util.Date());
		tempCal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH), tempCal.get(Calendar.DAY_OF_MONTH), tempCal.get(Calendar.HOUR_OF_DAY), tempCal.get(Calendar.MINUTE) + timeLater, 0);
		java.sql.Timestamp retStamp = new java.sql.Timestamp(tempCal.getTime().getTime());
		retStamp.setNanos(0);
		return retStamp;
	}

}